/*
 * Created on May 18, 2004
 *
 * Paros and its related class files.
 *
 * Paros is an HTTP/HTTPS proxy for assessing web application security.
 * Copyright (C) 2003-2004 Chinotec Technologies Company
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Clarified Artistic License
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Clarified Artistic License for more details.
 *
 * You should have received a copy of the Clarified Artistic License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
// ZAP: 2011/05/31 Added option to dynamically change the display
// ZAP: 2012/03/15 Changed so the change display option stays visually selected.
// ZAP: 2012/04/26 Removed the method setStatus(String) and instance variable
// "txtStatus".
// ZAP: 2013/07/23 Issue 738: Options to hide tabs
// ZAP: 2015/01/29 Issue 1489: Version number in window title
// ZAP: 2016/04/04 Do not require a restart to show/hide the tool bar
// ZAP: 2016/04/06 Fix layouts' issues
// ZAP: 2017/06/01 Issue 3555: setTitle() functionality moved in order to ensure consistent
// application
// ZAP: 2018/02/14 Add button for ResponsePanelPosition.TAB_SIDE_BY_SIDE (Issue 4331).
// ZAP: 2019/06/01 Normalise line endings.
// ZAP: 2019/06/05 Normalise format/style.
// ZAP: 2019/12/13 Display the primary proxy details (host:port) in the footer (Issue 2016).
// ZAP: 2020/09/29 Add support for dynamic Look and Feel switching (Issue 6201)
// ZAP: 2020/11/26 Use Log4j 2 classes for logging.
// ZAP: 2022/02/09 Remove method call no longer needed.
// ZAP: 2022/02/26 Remove code deprecated in 2.5.0
// ZAP: 2022/08/05 Address warns with Java 18 (Issue 7389).
package org.parosproxy.paros.view;

import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.extension.AbstractPanel;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.OptionsParam;
import org.parosproxy.paros.model.Session;
import org.zaproxy.zap.utils.DisplayUtils;
import org.zaproxy.zap.view.MainToolbarPanel;
import org.zaproxy.zap.view.ZapToggleButton;
import org.zaproxy.zap.view.widgets.PopupButton;

@SuppressWarnings("serial")
public class MainFrame extends AbstractFrame {

    private static final Logger LOGGER = LogManager.getLogger(MainFrame.class);

    private static final String TABS_VIEW_TOOL_TIP =
            Constant.messages.getString("view.toolbar.messagePanelsPosition.tabs");
    private static final String TAB_SIDE_BY_SIDE_VIEW_TOOL_TIP =
            Constant.messages.getString("view.toolbar.messagePanelsPosition.tabSideBySide");
    private static final String ABOVE_VIEW_TOOL_TIP =
            Constant.messages.getString("view.toolbar.messagePanelsPosition.above");
    private static final String DISABLED_ABOVE_VIEW_TOOL_TIP =
            Constant.messages.getString("view.toolbar.messagePanelsPosition.above.disabled");
    private static final String SIDE_BY_SIDE_VIEW_TOOL_TIP =
            Constant.messages.getString("view.toolbar.messagePanelsPosition.sideBySide");
    private static final String DISABLED_SIDE_BY_SIDE_VIEW_TOOL_TIP =
            Constant.messages.getString("view.toolbar.messagePanelsPosition.sideBySide.disabled");

    private static final long serialVersionUID = -1430550461546083192L;

    private final OptionsParam options;
    private JPanel paneContent = null;
    // ZAP: Removed instance variable (JLabel txtStatus). The status label that
    // was in the footer panel is no longer used.
    private final WorkbenchPanel paneStandard;
    private org.parosproxy.paros.view.MainMenuBar mainMenuBar = null;
    private JPanel paneDisplay = null;

    private MainToolbarPanel mainToolbarPanel = null;
    private MainFooterPanel mainFooterPanel = null;

    /**
     * The {@code ZapToggleButton} that sets whether or not the tabs should show the panels' names.
     *
     * <p>Lazily initialised.
     *
     * @see #getShowTabIconNamesButton()
     */
    private ZapToggleButton showTabIconNamesButton;

    /**
     * The {@code JButton} that shows all tabs.
     *
     * <p>Lazily initialised.
     *
     * @see #getShowAllTabsButton()
     */
    private JButton showAllTabsButton;

    /**
     * The {@code JButton} that hides all tabs (if hideable and not pinned).
     *
     * <p>Lazily initialised.
     *
     * @see #getHideAllTabsButton()
     */
    private JButton hideAllTabsButton;

    /**
     * The current workbench layout, never {@code null}.
     *
     * @see #setWorkbenchLayout(WorkbenchPanel.Layout)
     */
    private WorkbenchPanel.Layout workbenchLayout;

    /**
     * The {@code JToggleButton} that sets the layout {@link WorkbenchPanel.Layout#EXPAND_SELECT}.
     *
     * <p>Lazily initialised.
     *
     * @see #getExpandSelectLayoutButton()
     */
    private JToggleButton expandSelectLayoutButton;

    /**
     * The {@code JToggleButton} that sets the layout {@link WorkbenchPanel.Layout#EXPAND_STATUS}.
     *
     * <p>Lazily initialised.
     *
     * @see #getExpandStatusLayoutButton()
     */
    private JToggleButton expandStatusLayoutButton;

    /**
     * The {@code JToggleButton} that sets the layout {@link WorkbenchPanel.Layout#FULL}.
     *
     * <p>Lazily initialised.
     *
     * @see #getFullLayoutButton()
     */
    private JToggleButton fullLayoutButton;

    /**
     * The current position of the response panel, never {@code null}.
     *
     * @see #setResponsePanelPosition(WorkbenchPanel.ResponsePanelPosition)
     */
    private WorkbenchPanel.ResponsePanelPosition responsePanelPosition;

    /**
     * The {@code ZapToggleButton} that sets the response panel position {@link
     * WorkbenchPanel.ResponsePanelPosition#TABS_SIDE_BY_SIDE}.
     *
     * <p>Lazily initialised.
     *
     * @see #getTabsResponsePanelPositionButton()
     */
    private ZapToggleButton tabsResponsePanelPositionButton;

    /**
     * The {@code ZapToggleButton} that sets the response panel position {@link
     * WorkbenchPanel.ResponsePanelPosition#TAB_SIDE_BY_SIDE}.
     *
     * <p>Lazily initialised.
     *
     * @see #getTabSideBySideResponsePanelPositionButton()
     */
    private ZapToggleButton tabSideBySideResponsePanelPositionButton;

    /**
     * The {@code ZapToggleButton} that sets the response panel position {@link
     * WorkbenchPanel.ResponsePanelPosition#PANEL_ABOVE}.
     *
     * <p>Lazily initialised.
     *
     * @see #getAboveResponsePanelPositionButton()
     */
    private ZapToggleButton aboveResponsePanelPositionButton;

    /**
     * The {@code ZapToggleButton} that sets the response panel position {@link
     * WorkbenchPanel.ResponsePanelPosition#PANELS_SIDE_BY_SIDE}.
     *
     * <p>Lazily initialised.
     *
     * @see #getPanelsResponsePanelPositionButton()
     */
    private ZapToggleButton panelsResponsePanelPositionButton;

    private PopupButton lookAndFeelButton;

    /**
     * Constructs a {@code MainFrame} with the given options and request and response panels.
     *
     * @param options the options
     * @param requestPanel the main request panel
     * @param responsePanel the main response panel
     * @throws IllegalArgumentException if any of the parameters is {@code null}.
     * @since 2.5.0
     */
    public MainFrame(
            OptionsParam options, AbstractPanel requestPanel, AbstractPanel responsePanel) {
        super();

        if (options == null) {
            throw new IllegalArgumentException("Parameter options must not be null");
        }
        if (requestPanel == null) {
            throw new IllegalArgumentException("Parameter requestPanel must not be null");
        }
        if (responsePanel == null) {
            throw new IllegalArgumentException("Parameter responsePanel must not be null");
        }

        this.options = options;
        paneStandard = new WorkbenchPanel(options.getViewParam(), requestPanel, responsePanel);
        paneStandard.setLayout(new CardLayout());
        paneStandard.setName("paneStandard");

        initialize();

        applyViewOptions();
    }

    /** This method initializes this */
    private void initialize() {
        this.setJMenuBar(getMainMenuBar());
        this.setContentPane(getPaneContent());
        this.setPreferredSize(new Dimension(1000, 800));
        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        this.addWindowListener(
                new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {
                        getMainMenuBar().getMenuFileControl().exit();
                    }
                });

        this.setVisible(false);
    }

    /**
     * This method initializes paneContent
     *
     * @return JPanel
     */
    private JPanel getPaneContent() {
        if (paneContent == null) {

            paneContent = new JPanel();
            paneContent.setLayout(new BoxLayout(getPaneContent(), BoxLayout.Y_AXIS));
            paneContent.setEnabled(true);

            paneContent.add(getMainToolbarPanel(), null);

            paneContent.add(getPaneDisplay(), null);
            paneContent.add(getMainFooterPanel(), null);
        }
        return paneContent;
    }

    /**
     * Gets the {@code WorkbenchPanel}.
     *
     * @return the workbench panel
     * @since 2.2.0
     */
    public WorkbenchPanel getWorkbench() {
        return paneStandard;
    }

    /**
     * This method initializes mainMenuBar
     *
     * @return org.parosproxy.paros.view.MenuDisplay
     */
    public org.parosproxy.paros.view.MainMenuBar getMainMenuBar() {
        if (mainMenuBar == null) {
            mainMenuBar = new org.parosproxy.paros.view.MainMenuBar();
        }
        return mainMenuBar;
    }

    // ZAP: Removed the method getTxtStatus()

    // ZAP: Removed the method setStatus(String). The status label
    // ("txtStatus") that was in the footer panel is no longer used.

    /**
     * This method initializes paneDisplay
     *
     * @return JPanel
     */
    public JPanel getPaneDisplay() {
        if (paneDisplay == null) {
            paneDisplay = new JPanel();
            paneDisplay.setLayout(new CardLayout());
            paneDisplay.setName("paneDisplay");
            paneDisplay.add(getWorkbench(), getWorkbench().getName());
        }
        return paneDisplay;
    }

    // ZAP: Added main toolbar panel
    public MainToolbarPanel getMainToolbarPanel() {
        if (mainToolbarPanel == null) {
            mainToolbarPanel = new MainToolbarPanel();

            mainToolbarPanel.addToolBarComponent(getLookAndFeelButton());
            mainToolbarPanel.addSeparator();

            mainToolbarPanel.addButton(getShowAllTabsButton());
            mainToolbarPanel.addButton(getHideAllTabsButton());
            mainToolbarPanel.addButton(getShowTabIconNamesButton());
            mainToolbarPanel.addSeparator();

            ButtonGroup layoutsButtonGroup = new ButtonGroup();
            mainToolbarPanel.addButton(getExpandSelectLayoutButton());
            layoutsButtonGroup.add(getExpandSelectLayoutButton());
            mainToolbarPanel.addButton(getExpandStatusLayoutButton());
            layoutsButtonGroup.add(getExpandStatusLayoutButton());
            mainToolbarPanel.addButton(getFullLayoutButton());
            layoutsButtonGroup.add(getFullLayoutButton());
            mainToolbarPanel.addSeparator();

            ButtonGroup responsePanelPositionsButtonGroup = new ButtonGroup();
            mainToolbarPanel.addButton(getTabsResponsePanelPositionButton());
            responsePanelPositionsButtonGroup.add(getTabsResponsePanelPositionButton());
            mainToolbarPanel.addButton(getTabSideBySideResponsePanelPositionButton());
            responsePanelPositionsButtonGroup.add(getTabSideBySideResponsePanelPositionButton());
            mainToolbarPanel.addButton(getPanelsResponsePanelPositionButton());
            responsePanelPositionsButtonGroup.add(getPanelsResponsePanelPositionButton());
            mainToolbarPanel.addButton(getAboveResponsePanelPositionButton());
            responsePanelPositionsButtonGroup.add(getAboveResponsePanelPositionButton());
            mainToolbarPanel.addSeparator();
        }
        return mainToolbarPanel;
    }

    private JButton getShowAllTabsButton() {
        if (showAllTabsButton == null) {
            showAllTabsButton = new JButton();
            showAllTabsButton.setIcon(
                    new ImageIcon(
                            WorkbenchPanel.class.getResource(
                                    "/resource/icon/fugue/ui-tab-show.png")));
            showAllTabsButton.setToolTipText(Constant.messages.getString("menu.view.tabs.show"));
            DisplayUtils.scaleIcon(showAllTabsButton);

            showAllTabsButton.addActionListener(
                    new java.awt.event.ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            View.getSingleton().showAllTabs();
                        }
                    });
        }
        return showAllTabsButton;
    }

    private JButton getHideAllTabsButton() {
        if (hideAllTabsButton == null) {
            hideAllTabsButton = new JButton();
            hideAllTabsButton.setIcon(
                    new ImageIcon(
                            WorkbenchPanel.class.getResource(
                                    "/resource/icon/fugue/ui-tab-hide.png")));
            hideAllTabsButton.setToolTipText(Constant.messages.getString("menu.view.tabs.hide"));
            DisplayUtils.scaleIcon(hideAllTabsButton);

            hideAllTabsButton.addActionListener(
                    new java.awt.event.ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            View.getSingleton().hideAllTabs();
                        }
                    });
        }
        return hideAllTabsButton;
    }

    private JToggleButton getShowTabIconNamesButton() {
        if (showTabIconNamesButton == null) {
            showTabIconNamesButton = new ZapToggleButton();
            showTabIconNamesButton.setIcon(
                    new ImageIcon(
                            WorkbenchPanel.class.getResource("/resource/icon/ui_tab_icon.png")));
            showTabIconNamesButton.setToolTipText(
                    Constant.messages.getString("view.toolbar.showNames"));
            showTabIconNamesButton.setSelectedIcon(
                    new ImageIcon(
                            WorkbenchPanel.class.getResource("/resource/icon/ui_tab_text.png")));
            showTabIconNamesButton.setSelectedToolTipText(
                    Constant.messages.getString("view.toolbar.showIcons"));
            showTabIconNamesButton.setSelected(
                    Model.getSingleton().getOptionsParam().getViewParam().getShowTabNames());
            DisplayUtils.scaleIcon(showTabIconNamesButton);

            showTabIconNamesButton.addActionListener(
                    new java.awt.event.ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent evt) {
                            boolean showTabNames = getShowTabIconNamesButton().isSelected();
                            setShowTabNames(showTabNames);
                            Model.getSingleton()
                                    .getOptionsParam()
                                    .getViewParam()
                                    .setShowTabNames(showTabNames);
                            try {
                                Model.getSingleton()
                                        .getOptionsParam()
                                        .getViewParam()
                                        .getConfig()
                                        .save();
                            } catch (ConfigurationException e) {
                                LOGGER.error(e.getMessage(), e);
                            }
                        }
                    });
        }
        return showTabIconNamesButton;
    }

    private JToggleButton getExpandSelectLayoutButton() {
        if (expandSelectLayoutButton == null) {
            expandSelectLayoutButton =
                    new JToggleButton(
                            new ChangeWorkbenchLayoutAction(
                                    WorkbenchPanel.class.getResource(
                                            "/resource/icon/expand_sites.png"),
                                    WorkbenchPanel.Layout.EXPAND_SELECT));
            expandSelectLayoutButton.setToolTipText(
                    Constant.messages.getString("view.toolbar.expandSites"));
        }
        return expandSelectLayoutButton;
    }

    private JToggleButton getExpandStatusLayoutButton() {
        if (expandStatusLayoutButton == null) {
            expandStatusLayoutButton =
                    new JToggleButton(
                            new ChangeWorkbenchLayoutAction(
                                    WorkbenchPanel.class.getResource(
                                            "/resource/icon/expand_info.png"),
                                    WorkbenchPanel.Layout.EXPAND_STATUS));
            expandStatusLayoutButton.setToolTipText(
                    Constant.messages.getString("view.toolbar.expandInfo"));
        }
        return expandStatusLayoutButton;
    }

    private JToggleButton getFullLayoutButton() {
        if (fullLayoutButton == null) {
            fullLayoutButton =
                    new JToggleButton(
                            new ChangeWorkbenchLayoutAction(
                                    WorkbenchPanel.class.getResource(
                                            "/resource/icon/expand_full.png"),
                                    WorkbenchPanel.Layout.FULL));
            fullLayoutButton.setToolTipText(Constant.messages.getString("view.toolbar.expandFull"));
        }
        return fullLayoutButton;
    }

    private ZapToggleButton getTabsResponsePanelPositionButton() {
        if (tabsResponsePanelPositionButton == null) {
            tabsResponsePanelPositionButton =
                    new ZapToggleButton(
                            new SetResponsePanelPositionAction(
                                    WorkbenchPanel.class.getResource(
                                            "/resource/icon/layout_tabbed.png"),
                                    WorkbenchPanel.ResponsePanelPosition.TABS_SIDE_BY_SIDE));
            tabsResponsePanelPositionButton.setToolTipText(TABS_VIEW_TOOL_TIP);
        }
        return tabsResponsePanelPositionButton;
    }

    private ZapToggleButton getTabSideBySideResponsePanelPositionButton() {
        if (tabSideBySideResponsePanelPositionButton == null) {
            tabSideBySideResponsePanelPositionButton =
                    new ZapToggleButton(
                            new SetResponsePanelPositionAction(
                                    WorkbenchPanel.class.getResource(
                                            "/resource/icon/layout_tabbed_split.png"),
                                    WorkbenchPanel.ResponsePanelPosition.TAB_SIDE_BY_SIDE));
            tabSideBySideResponsePanelPositionButton.setToolTipText(TAB_SIDE_BY_SIDE_VIEW_TOOL_TIP);
        }
        return tabSideBySideResponsePanelPositionButton;
    }

    private ZapToggleButton getPanelsResponsePanelPositionButton() {
        if (panelsResponsePanelPositionButton == null) {
            panelsResponsePanelPositionButton =
                    new ZapToggleButton(
                            new SetResponsePanelPositionAction(
                                    WorkbenchPanel.class.getResource(
                                            "/resource/icon/layout_horizontal_split.png"),
                                    WorkbenchPanel.ResponsePanelPosition.PANELS_SIDE_BY_SIDE));
            panelsResponsePanelPositionButton.setToolTipText(SIDE_BY_SIDE_VIEW_TOOL_TIP);
            panelsResponsePanelPositionButton.setDisabledToolTipText(
                    DISABLED_SIDE_BY_SIDE_VIEW_TOOL_TIP);
        }
        return panelsResponsePanelPositionButton;
    }

    private ZapToggleButton getAboveResponsePanelPositionButton() {
        if (aboveResponsePanelPositionButton == null) {
            aboveResponsePanelPositionButton =
                    new ZapToggleButton(
                            new SetResponsePanelPositionAction(
                                    WorkbenchPanel.class.getResource(
                                            "/resource/icon/layout_vertical_split.png"),
                                    WorkbenchPanel.ResponsePanelPosition.PANEL_ABOVE));
            aboveResponsePanelPositionButton.setToolTipText(ABOVE_VIEW_TOOL_TIP);
            aboveResponsePanelPositionButton.setDisabledToolTipText(DISABLED_ABOVE_VIEW_TOOL_TIP);
        }
        return aboveResponsePanelPositionButton;
    }

    private PopupButton getLookAndFeelButton() {
        if (lookAndFeelButton == null) {
            lookAndFeelButton =
                    new PopupButton() {
                        private static final long serialVersionUID = 1L;

                        @Override
                        public List<String> getMenuItemNames() {
                            List<String> list = new ArrayList<>();
                            UIManager.LookAndFeelInfo[] looks =
                                    UIManager.getInstalledLookAndFeels();
                            for (UIManager.LookAndFeelInfo look : looks) {
                                list.add(look.getName());
                            }
                            return list;
                        }

                        @Override
                        public void menuItemSelected(String option) {
                            UIManager.LookAndFeelInfo[] looks =
                                    UIManager.getInstalledLookAndFeels();
                            for (UIManager.LookAndFeelInfo look : looks) {
                                if (look.getName().equals(option)) {
                                    options.getViewParam().setLookAndFeelInfo(look);
                                }
                            }
                        }

                        @Override
                        public String getSelectedMenuItem() {
                            return options.getViewParam().getLookAndFeel();
                        }
                    };
            lookAndFeelButton.setIcon(
                    new ImageIcon(
                            WorkbenchPanel.class.getResource(
                                    "/resource/icon/fugue/ui-color-picker-switch.png")));
            lookAndFeelButton.setToolTipText(
                    Constant.messages.getString("view.toolbar.switchLookAndFeel"));
        }
        return lookAndFeelButton;
    }

    // ZAP: Added footer toolbar panel
    public MainFooterPanel getMainFooterPanel() {
        if (mainFooterPanel == null) {
            mainFooterPanel = new MainFooterPanel();
        }
        return mainFooterPanel;
    }

    /**
     * Applies the view options to the main frame components.
     *
     * <p>It controls the visibility of the main tool bar, the layout and response panel position of
     * the workbench panel and if the tabs should display the panels' names.
     *
     * @since 2.5.0
     * @see #setMainToolbarVisible(boolean)
     * @see #setWorkbenchLayout(WorkbenchPanel.Layout)
     * @see #setResponsePanelPosition(WorkbenchPanel.ResponsePanelPosition)
     * @see #setShowTabNames(boolean)
     * @see org.parosproxy.paros.extension.option.OptionsParamView
     */
    public void applyViewOptions() {
        setMainToolbarVisible(options.getViewParam().isShowMainToolbar());

        setWorkbenchLayout(
                WorkbenchPanel.Layout.getLayout(options.getViewParam().getDisplayOption()));

        WorkbenchPanel.ResponsePanelPosition position =
                WorkbenchPanel.ResponsePanelPosition.TABS_SIDE_BY_SIDE;
        try {
            position =
                    WorkbenchPanel.ResponsePanelPosition.valueOf(
                            options.getViewParam().getResponsePanelPosition());
        } catch (IllegalArgumentException e) {
            LOGGER.warn("Failed to restore the position of response panel: ", e);
        }
        setResponsePanelPosition(position);

        setShowTabNames(options.getViewParam().getShowTabNames());
    }

    /**
     * Sets the layout of the workbench panel.
     *
     * <p>If the layout is already set no further action is taken, otherwise updates the main tool
     * bar buttons, the workbench panel and the configurations file.
     *
     * @param layout the new layout of the workbench panel
     * @throws IllegalArgumentException if the given parameter is {@code null}.
     * @since 2.5.0
     * @see #getWorkbenchLayout()
     * @see #setResponsePanelPosition(WorkbenchPanel.ResponsePanelPosition)
     */
    public void setWorkbenchLayout(WorkbenchPanel.Layout layout) {
        if (layout == null) {
            throw new IllegalArgumentException("Parameter layout must not be null.");
        }

        if (workbenchLayout == layout) {
            return;
        }

        workbenchLayout = layout;

        switch (workbenchLayout) {
            case EXPAND_STATUS:
                getExpandStatusLayoutButton().setSelected(true);
                setResponsePanelPositionButtonsEnabled(true);
                break;
            case FULL:
                getFullLayoutButton().setSelected(true);
                setResponsePanelPositionButtonsEnabled(false);
                break;
            case EXPAND_SELECT:
            default:
                getExpandSelectLayoutButton().setSelected(true);
                setResponsePanelPositionButtonsEnabled(true);
                break;
        }

        getWorkbench().setWorkbenchLayout(workbenchLayout);
        options.getViewParam().setDisplayOption(workbenchLayout.getId());
    }

    /**
     * Sets whether or not the buttons that control the response panel position should be enabled.
     *
     * @param enabled {@code true} if the buttons should be enabled, {@code false} otherwise.
     */
    private void setResponsePanelPositionButtonsEnabled(boolean enabled) {
        panelsResponsePanelPositionButton.setEnabled(enabled);
        aboveResponsePanelPositionButton.setEnabled(enabled);
    }

    /**
     * Gets the workbench layout.
     *
     * @return the workbench layout, never {@code null}.
     * @since 2.5.0
     * @see #setWorkbenchLayout(WorkbenchPanel.Layout)
     */
    public WorkbenchPanel.Layout getWorkbenchLayout() {
        return workbenchLayout;
    }

    /**
     * Sets the position of the response panel. Should be considered a hint, not all workbench
     * layouts might use this setting.
     *
     * <p>If the position is already set no further action is taken, otherwise updates the main tool
     * bar buttons, the workbench panel and the configurations file.
     *
     * @param position the new position of the response panel
     * @throws IllegalArgumentException if the given parameter is {@code null}.
     * @since 2.5.0
     * @see #getResponsePanelPosition()
     * @see #setWorkbenchLayout(org.parosproxy.paros.view.WorkbenchPanel.Layout)
     */
    public void setResponsePanelPosition(WorkbenchPanel.ResponsePanelPosition position) {
        if (position == null) {
            throw new IllegalArgumentException("Parameter position must not be null.");
        }

        if (responsePanelPosition == position) {
            return;
        }

        responsePanelPosition = position;

        switch (position) {
            case PANEL_ABOVE:
                aboveResponsePanelPositionButton.setSelected(true);
                break;
            case PANELS_SIDE_BY_SIDE:
                panelsResponsePanelPositionButton.setSelected(true);
                break;
            case TAB_SIDE_BY_SIDE:
                tabSideBySideResponsePanelPositionButton.setSelected(true);
                break;
            case TABS_SIDE_BY_SIDE:
            default:
                tabsResponsePanelPositionButton.setSelected(true);
        }

        getWorkbench().setResponsePanelPosition(responsePanelPosition);
        options.getViewParam().setResponsePanelPosition(responsePanelPosition.toString());
    }

    /**
     * Gets the response panel position.
     *
     * @return the response panel position, never {@code null}.
     * @since 2.5.0
     * @see #setResponsePanelPosition(WorkbenchPanel.ResponsePanelPosition)
     */
    public WorkbenchPanel.ResponsePanelPosition getResponsePanelPosition() {
        return responsePanelPosition;
    }

    /**
     * Sets whether or not the tabs should display the name of the panels.
     *
     * @param showTabNames {@code true} if the names should be shown, {@code false} otherwise.
     * @since 2.5.0
     */
    public void setShowTabNames(boolean showTabNames) {
        getWorkbench().toggleTabNames(showTabNames);
        getShowTabIconNamesButton().setSelected(showTabNames);
    }

    /**
     * Sets the title of the main window.
     *
     * <p>The actual title set is the current session name, then the filename of the session (if
     * persisted), followed by the program name and version.
     *
     * @param session the {@code Session} from which the window title is being built
     * @see Constant#PROGRAM_NAME
     * @see Constant#PROGRAM_VERSION
     * @since 2.7.0
     */
    public void setTitle(Session session) {
        StringBuilder strBuilder = new StringBuilder();
        if (session != null) {
            strBuilder.append(session.getSessionName()).append(" - ");
            if (!session.isNewState()) {
                File file = new File(session.getFileName());
                strBuilder.append(file.getName().replaceAll(".session\\z", "")).append(" - ");
            }
        }
        strBuilder.append(Constant.PROGRAM_NAME).append(' ').append(Constant.PROGRAM_VERSION);
        super.setTitle(strBuilder.toString());
    }

    /**
     * Sets the title of the main window.
     *
     * <p>The actual title set is the given {@code title} followed by the program name and version.
     *
     * @see Constant#PROGRAM_NAME
     * @see Constant#PROGRAM_VERSION
     * @deprecated as of 2.7.0, replaced by {@link #setTitle(Session)}
     */
    @Override
    @Deprecated
    public void setTitle(String title) {
        StringBuilder strBuilder = new StringBuilder();
        if (title != null && !title.isEmpty()) {
            strBuilder.append(title);
            strBuilder.append(" - ");
        }
        strBuilder.append(Constant.PROGRAM_NAME).append(' ').append(Constant.PROGRAM_VERSION);
        super.setTitle(strBuilder.toString());
    }

    /**
     * Sets whether or not the main tool bar should be visible.
     *
     * @param visible {@code true} if the main tool bar should be visible, {@code false} otherwise.
     * @since 2.5.0
     */
    public void setMainToolbarVisible(boolean visible) {
        getMainToolbarPanel().setVisible(visible);
    }

    /**
     * An {@code Action} that changes the layout of the workbench panels.
     *
     * @see MainFrame#setWorkbenchLayout(WorkbenchPanel.Layout)
     */
    private class ChangeWorkbenchLayoutAction extends AbstractAction {

        private static final long serialVersionUID = 8323387638733162321L;

        private final WorkbenchPanel.Layout layout;

        public ChangeWorkbenchLayoutAction(URL iconURL, WorkbenchPanel.Layout layout) {
            super("", DisplayUtils.getScaledIcon(new ImageIcon(iconURL)));

            this.layout = layout;
        }

        @Override
        public void actionPerformed(ActionEvent evt) {
            setWorkbenchLayout(layout);
        }
    }

    /**
     * An {@code Action} that changes the position of the response panel.
     *
     * @see
     *     MainFrame#setResponsePanelPosition(org.parosproxy.paros.view.WorkbenchPanel.ResponsePanelPosition)
     */
    private class SetResponsePanelPositionAction extends AbstractAction {

        private static final long serialVersionUID = 756133292459364854L;

        private final WorkbenchPanel.ResponsePanelPosition position;

        public SetResponsePanelPositionAction(
                URL iconLocation, WorkbenchPanel.ResponsePanelPosition position) {
            super("", new ImageIcon(iconLocation));

            this.position = position;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setResponsePanelPosition(position);
        }
    }
}
